﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using eWallet.Collections.Generic;

namespace eWallet.Windows.Controls
{
	/// <summary>
	/// Interaction logic for BreadCrumbPath.xaml
	/// </summary>
	public partial class BreadCrumbPath : UserControl
	{
		public BreadCrumbPath()
		{
			InitializeComponent();

			this.AutoNavigate = true;
			this.Separator = "/";
			this.ShowHomeLabel = true;
			this.HomeLabelText = "Home";
		}

		private EventHandler<ItemClickedEventArgs> ItemClickedHandler;
		public event EventHandler<ItemClickedEventArgs> ItemClicked
		{
			add { this.ItemClickedHandler += value; }
			remove { this.ItemClickedHandler -= value; }
		}

		private bool SupressItemsChangedEvent = false;
		private EventHandler ItemsChangedHandler;
		public event EventHandler ItemsChanged
		{
			add { this.ItemsChangedHandler += value; }
			remove { this.ItemsChangedHandler -= value; }
		}

		private EventHandler ShowHomeLabelChangedHandler;
		public event EventHandler ShowHomeLabelChanged
		{
			add { this.ShowHomeLabelChangedHandler += value; }
			remove { this.ShowHomeLabelChangedHandler -= value; }
		}

		public bool AutoNavigate { get; set; }

		public string HomeLabelText
		{
			get { return this.HomeLabel.Content as string; }
			set { this.HomeLabel.Content = value; }
		}

		public bool ShowHomeLabel
		{
			get { return this.HomeLabel.Visibility == Visibility.Visible; }
			set
			{
				if (value != this.ShowHomeLabel)
				{
					if (value)
					{
						this.HomeLabel.Visibility = Visibility.Visible;
						this.SetFirstSeparatorVisibility(true);
					}
					else
					{
						this.HomeLabel.Visibility = Visibility.Collapsed;
						this.SetFirstSeparatorVisibility(false);
					}
				}
			}
		}

		private EventfulList<string> _Items;
		public IList<string> Items
		{
			get
			{
				if (null == _Items)
				{
					_Items = new EventfulList<string>();
					_Items.Added += delegate(object sender, ListItemEventArgs<string> e)
					{
						this.AddItem(e.Item);
						if (!this.SupressItemsChangedEvent)
						{
							this.OnItemsChanged(EventArgs.Empty);
						}
					};
					_Items.Cleared += delegate(object sender, EventArgs e)
					{
						if (this.MainWrapper.Children.Count > 0)
						{
							this.MainWrapper.Children.Clear();
							if (!this.SupressItemsChangedEvent)
							{
								this.OnItemsChanged(EventArgs.Empty);
							}
						}
					};
					_Items.Removed += delegate(object sender, ListItemEventArgs<string> e)
					{
						this.MainWrapper.Children.RemoveAt(e.Index);
						if (!this.SupressItemsChangedEvent)
						{
							this.OnItemsChanged(EventArgs.Empty);
						}
					};
				}
				return _Items;
			}
		}

		private string _Separator;
		public string Separator
		{
			get { return _Separator; }
			set
			{
				if (!string.Equals(this.Separator, value))
				{
					_Separator = value;
					this.ResetSeparator();
				}
			}
		}



		public void RemoveItemsFrom(int index)
		{
			this.SupressItemsChangedEvent = true;
			try
			{
				while (index < this.Items.Count)
				{
					this.Items.RemoveAt(index);
				}
			}
			finally
			{
				this.SupressItemsChangedEvent = false;
			}

			this.OnItemsChanged(EventArgs.Empty);
		}



		protected virtual void OnItemClicked(ItemClickedEventArgs e)
		{
			if (null != this.ItemClickedHandler)
			{
				this.ItemClickedHandler(this, e);
			}
		}

		protected virtual void OnItemsChanged(EventArgs e)
		{
			if (null != this.ItemsChangedHandler)
			{
				this.ItemsChangedHandler(this, e);
			}
		}

		protected virtual void OnShowHomeLabelChanged(EventArgs e)
		{
			if (null != this.ShowHomeLabelChangedHandler)
			{
				this.ShowHomeLabelChangedHandler(this, e);
			}
		}

		private void AddItem(string label)
		{
			WrapPanel panel = new WrapPanel();

			Label separator = new Label() { Content = this.Separator };
			if (!this.ShowHomeLabel && this.MainWrapper.Children.Count == 0)
			{
				separator.Visibility = Visibility.Collapsed;
			}
			panel.Children.Add(separator);

			Label item = new Label() { Content = label };
			item.Cursor = Cursors.Hand;
			item.MouseLeftButtonUp += this.CrumbItem_MouseLeftButtonUp;
			panel.Children.Add(item);

			this.MainWrapper.Children.Add(panel);
		}



		private void CrumbItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
		{
			Label lbl = (Label)sender;
			for(int i = 0; i < this.MainWrapper.Children.Count; i++)
			{
				WrapPanel panel = (WrapPanel)this.MainWrapper.Children[i];
				if(panel.Children.Contains(lbl))
				{
					if (this.AutoNavigate)
					{
						this.RemoveItemsFrom(i + 1);
					}
					this.OnItemClicked(new ItemClickedEventArgs(i));
					break;
				}
			}
		}

		private void ResetSeparator()
		{
			for (int i = 0; i < this.MainWrapper.Children.Count; i++)
			{
				WrapPanel panel = (WrapPanel)this.MainWrapper.Children[i];
				Label lbl = (Label)panel.Children[0];
				lbl.Content = this.Separator;
			}
		}

		private void SetFirstSeparatorVisibility(bool visible)
		{
			UIElement separator = null;

			if (this.MainWrapper.Children.Count > 0)
			{
				WrapPanel panel = (WrapPanel)this.MainWrapper.Children[0];
				if (panel.Children.Count > 0)
				{
					separator = panel.Children[0];
				}
			}

			if (null != separator)
			{
				if (visible)
				{
					separator.Visibility = Visibility.Visible;
				}
				else
				{
					separator.Visibility = Visibility.Collapsed;
				}
			}
		}

		private void HomeLabel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
		{
			this.Items.Clear();
		}
	}
}
